﻿using Serilog;
using Serilog.Events;

namespace Net7Docker.Extensions
{
    /// <summary>
    /// Serilog安装
    /// </summary>
    public static class SerilogSetup
    {
        //日志控制台模板
        private static readonly string logConsoleTemplate = "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}";
        //日志文件模板
        private static readonly string logTemplate = "{NewLine}时间:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}日志等级:{Level}{NewLine}线程ID:{ThreadId} 线程名:{ThreadName}{NewLine}所在类:{SourceContext}{NewLine}日志信息:{Message}{NewLine}{Exception}";


        //添加Serilog扩展方法
        public static void AddSerilog(this WebApplicationBuilder builder)
        {
            //// 打印到控制台
            //// 生产环境中可以不向控制台打印
            //builder.UseSerilog((context, logger) =>
            //{
            //    // 添加此句后可以在“执行上下文”中动态添加和删除属性
            //    logger.Enrich.FromLogContext();

            //    logger.MinimumLevel.Information();
            //    logger.Enrich.WithThreadId();
            //    logger.Enrich.WithThreadName();

            //    logger.WriteTo.Logger(lg => lg.WriteTo.Async(a =>
            //            a.Console(outputTemplate: logTemplate)));
            //});

            // 打印到文件
            builder.Host.UseSerilog((context, logger) =>
            {
                //Serilog日志最小级别Debug
                logger.MinimumLevel.Information();

                //微软日志级别调到警告及其以上
                logger.MinimumLevel.Override("Microsoft", LogEventLevel.Information);

                //注册日志上下文
                logger.Enrich.FromLogContext();

                //日志带线程Id
                logger.Enrich.WithThreadId();

                //日志带线程名称
                logger.Enrich.WithThreadName();

                //输出到控制台
                //logger.WriteTo.Logger(lg => lg.WriteTo.Async(a => a.Console(outputTemplate: logTemplate)));
                //logger.WriteTo.Console(new JsonFormatter());
                //logger.WriteTo.Console(outputTemplate: "[{Timestamp:yyyy-HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}");
                logger.WriteTo.Logger(lg => lg.WriteTo.Async(a => a.Console(outputTemplate: logConsoleTemplate)));

                // 输出到数据库
                logger.WriteTo.MySQL(connectionString: builder.Configuration.GetConnectionString("DbConnectionString"), tableName: "Logs"); 

                //按日志级别输出到文件
                //logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Debug).WriteTo.Async(a => a.File("Logs/Debug/log.txt", rollingInterval: RollingInterval.Day, outputTemplate: logTemplate)));
                //logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Information).WriteTo.Async(a => a.File("Logs/Info/log.txt", rollingInterval: RollingInterval.Day, outputTemplate: logTemplate)));
                //logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Warning).WriteTo.Async(a => a.File("Logs/Warn/log.txt", rollingInterval: RollingInterval.Day, outputTemplate: logTemplate)));
                //logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Error).WriteTo.Async(a => a.File("Logs/Error/log.txt", rollingInterval: RollingInterval.Day, outputTemplate: logTemplate)));
                //logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Fatal).WriteTo.Async(a => a.File("Logs/Fatal/log.txt", rollingInterval: RollingInterval.Day, outputTemplate: logTemplate)));

                //不分日志级别打印日志到文件夹
                logger.WriteTo.Logger(lg => lg.WriteTo.Async(a => a.File(Path.Combine("Logs", @"log.txt"), rollingInterval: RollingInterval.Day))); ;

            });
        }
    }
}
